﻿using System;
using System.Collections.Generic;
using System.Data;

namespace CubeTimer
{
  public class CubeTimesCollection : List<CubeTime>
  {
    public TimeSpan GetLastTime()
    {
      return Count > 0 ? this[Count - 1].Time : new TimeSpan(1, 0, 0);
    }

    public TimeSpan GetBestTime()
    {
      if (Count > 0)
      {
        TimeSpan bestTime = new TimeSpan(1, 0, 0);
        foreach (CubeTime cubeTime in this)
        {
          if (cubeTime.Time < bestTime)
          {
            bestTime = cubeTime.Time;
          }
        }
        return bestTime;
      }
      return new TimeSpan();
    }

    public TimeSpan GetBestTime(DateTime date)
    {
      if (Count == 0) return new TimeSpan();
      TimeSpan bestTime = new TimeSpan(1, 0, 0);
      foreach (CubeTime cubeTime in this)
        if (cubeTime.Time < bestTime && cubeTime.When.Date >= date.Date)
          bestTime = cubeTime.Time;
      return bestTime;
    }

    public TimeSpan GetAverageTime(int num)
    {
      if (num == 0) return new TimeSpan(1, 0, 0);
      long ticks = 0;
      if (Count >= num)
      {
        var items = GetLastItems(num);
        foreach (var item in items)
        {
          ticks += item.ElapsedTicks;
        }
      }
      return new TimeSpan(ticks / num);
    }

    public TimeSpan GetAverageTime(int num, DateTime date)
    {
      CubeTimesCollection cubeTimes = GetItems(date);
      return cubeTimes.GetAverageTime(cubeTimes.Count);
    }

    private List<CubeTime> GetLastItems(int num)
    {
      if (num == Count) return this;
      var times = new List<CubeTime>();
      var timesCounter = 0;
      for (var index = 0; index < Count; index++, timesCounter++)
      {
        if (timesCounter >= num) break;
        times.Add(this[index]); ;
      }
      return times;
    }

    private CubeTimesCollection GetItems(DateTime date)
    {
      CubeTimesCollection collection = new CubeTimesCollection();
      collection.AddRange(FindAll(cubeTime => cubeTime.When >= date.Date));
      return collection;
    }

    public DataTable ToDataTable()
    {
      DataTable dt = new DataTable();
      dt.Columns.Add(new DataColumn("When") {DataType = typeof (DateTime)});
      dt.Columns.Add(new DataColumn("Time") {DataType = typeof (long)});
      dt.Columns.Add(new DataColumn("Values") { DataType = typeof(CubeTimesCollection) });
      Dictionary<DateTime, CubeTimesCollection> times = new Dictionary<DateTime, CubeTimesCollection>();
      foreach (CubeTime time in this)
      {
        if (times.ContainsKey(time.When.Date))
          times[time.When.Date].Add(time);
        else
          times.Add(time.When.Date, new CubeTimesCollection {time});
      }
      foreach (KeyValuePair<DateTime, CubeTimesCollection> time in times)
      {
        DataRow row = dt.NewRow();
        row["When"] = time.Key;
        row["Time"] = time.Value.GetAverageTime(time.Value.Count).TotalSeconds;
        row["Values"] = time.Value;
        dt.Rows.Add(row);
      }
      return dt;
    }

  }
}
